package cn.designPattern.dp.creator._4_singleton.example1;

import java.util.Date;

/*
优点：
● 由于单例模式在内存中只有一个实例，减少了内存开支，特别是一个对象需要频繁地创建、销毁时，而且创建或销毁时性能又无法优化，单例模式的优势就非常明显。
● 由于单例模式只生成一个实例，所以减少了系统的性能开销，当一个对象的产生需要比较多的资源时，如读取配置、产生其他依赖对象时，则可以通过在应用启动时直接产生一
    个单例对象，然后用永久驻留内存的方式来解决（在Java EE中采用单例模式时需要注意JVM垃圾回收机制）。
● 单例模式可以避免对资源的多重占用，例如一个写文件动作，由于只有一个实例存在内存中，避免对同一个资源文件的同时写操作。
● 单例模式可以在系统设置全局的访问点，优化和共享资源访问，例如可以设计一个单例类，负责所有数据表的映射处理

缺点：
    ● 单例没有接口，扩展很困难，若要扩展，除了修改代码基本上没有第二种途径可以实现。
    ● 单例模式对测试是不利的。在并行开发环境中，如果单例模式没有完成，是不能进行测试的，没有接口也不能使用mock的方式虚拟一个对象
    ● 单例模式与单一职责原则有冲突。一个类应该只实现一个逻辑，而不关心它是否是单例的，是不是要单例取决于环境，单例模式把“要单例”和业务逻辑融合在一个类中

使用场景：
    ● 唯一id
    ● 在整个项目中需要一个共享访问点或共享数据，例如一个Web页面上的计数器，可以不用把每次刷新都记录到数据库中，使用单例模式保持计数器的值，并确保是线程安全的；
    ● 创建一个对象需要消耗的资源过多，如要访问IO和数据库等资源。 所以也有用池的。
    ● 需要定义大量的静态常量和静态方法（如工具类）的环境，可以采用单例模式（当然，也可以直接声明为static的方式。最后再内存占的不是一样的而已）。

区别：
    static跟单例,它们之间的确很类似,实用类通常也会采用私有化的构造方法来避免其有实例。
    但它们还是有很多不同的,比如实用类不保存状态,仅提供一些静态方法或静态属性让你使用,而单例类是有状态的。
    实用类不能用于继承多态（final类）,而单例虽然实例唯一,却是可以有子类来继承。实用类只不过是一些方法属性的集合,而单例却是有着唯一的对象实例。
    在运用中还得仔细分析再作决定用哪一种方式。
 */
public class Client {
    public static void main(String[] args) {
        Singleton singleton = Singleton.getSingleton();
        Singleton singleton1 = Singleton.getSingleton();
        System.out.println("singleton1 = " + singleton1);
        System.out.println("singleton = " + singleton);
        System.out.println(singleton == singleton1);
        System.out.println(new Date() == new Date());
    }
}

/*
有个重要的，单例要设计多线程情况。比如example2
 */
